/**
 * 前端数据迭代器模式实现
 * 用于Vue组件中的数据遍历和状态管理
 */

// 抽象迭代器基类
class DataIterator {
  constructor() {
    if (this.constructor === DataIterator) {
      throw new Error('Cannot instantiate abstract class DataIterator')
    }
  }

  [Symbol.iterator]() {
    return this
  }

  next() {
    throw new Error('next() method must be implemented')
  }
}

// 分页数据迭代器
export class PaginatedIterator extends DataIterator {
  constructor(data, pageSize = 10) {
    super()
    this.data = data || []
    this.pageSize = pageSize
    this.currentPage = 0
    this.totalPages = Math.ceil(this.data.length / pageSize)
  }

  next() {
    if (this.currentPage >= this.totalPages) {
      return { done: true }
    }

    const start = this.currentPage * this.pageSize
    const end = Math.min(start + this.pageSize, this.data.length)
    const pageData = this.data.slice(start, end)

    const result = {
      value: {
        page: this.currentPage + 1,
        totalPages: this.totalPages,
        data: pageData,
        hasNext: this.currentPage < this.totalPages - 1,
        hasPrev: this.currentPage > 0,
        totalItems: this.data.length
      },
      done: false
    }

    this.currentPage++
    return result
  }

  reset() {
    this.currentPage = 0
  }

  goToPage(page) {
    if (page >= 0 && page < this.totalPages) {
      this.currentPage = page
    }
  }
}

// 过滤数据迭代器
export class FilteredIterator extends DataIterator {
  constructor(data, filterFn) {
    super()
    this.data = data || []
    this.filterFn = filterFn || (() => true)
    this.index = 0
    this.filteredData = this.data.filter(this.filterFn)
  }

  next() {
    if (this.index >= this.filteredData.length) {
      return { done: true }
    }

    const result = {
      value: {
        item: this.filteredData[this.index],
        index: this.index,
        originalIndex: this.data.indexOf(this.filteredData[this.index]),
        isFirst: this.index === 0,
        isLast: this.index === this.filteredData.length - 1,
        total: this.filteredData.length
      },
      done: false
    }

    this.index++
    return result
  }

  updateFilter(newFilterFn) {
    this.filterFn = newFilterFn
    this.filteredData = this.data.filter(this.filterFn)
    this.index = 0
  }

  reset() {
    this.index = 0
  }
}

// 医生列表迭代器
export class DoctorListIterator extends DataIterator {
  constructor(doctors, filters = {}) {
    super()
    this.doctors = doctors || []
    this.filters = filters
    this.index = 0
    this.applyFilters()
  }

  applyFilters() {
    let filtered = [...this.doctors]

    if (this.filters.department) {
      filtered = filtered.filter(doctor => 
        doctor.department?.id === this.filters.department
      )
    }

    if (this.filters.minRating) {
      filtered = filtered.filter(doctor => 
        doctor.rating >= this.filters.minRating
      )
    }

    if (this.filters.maxFee) {
      filtered = filtered.filter(doctor => 
        doctor.consultation_fee <= this.filters.maxFee
      )
    }

    if (this.filters.specialties) {
      filtered = filtered.filter(doctor =>
        doctor.specialties?.some(specialty => 
          this.filters.specialties.includes(specialty)
        )
      )
    }

    this.filteredDoctors = filtered
  }

  next() {
    if (this.index >= this.filteredDoctors.length) {
      return { done: true }
    }

    const doctor = this.filteredDoctors[this.index]
    const result = {
      value: {
        id: doctor.id,
        name: doctor.name,
        title: doctor.title,
        department: doctor.department?.name,
        rating: doctor.rating,
        fee: doctor.consultation_fee,
        avatar: doctor.avatar,
        specialties: doctor.specialties,
        isRecommended: doctor.is_featured,
        index: this.index,
        total: this.filteredDoctors.length
      },
      done: false
    }

    this.index++
    return result
  }

  updateFilters(newFilters) {
    this.filters = { ...this.filters, ...newFilters }
    this.applyFilters()
    this.index = 0
  }

  reset() {
    this.index = 0
  }
}

// 预约记录迭代器
export class AppointmentIterator extends DataIterator {
  constructor(appointments, groupBy = null) {
    super()
    this.appointments = appointments || []
    this.groupBy = groupBy
    this.index = 0
    this.processData()
  }

  processData() {
    if (this.groupBy === 'status') {
      this.groupedData = this.groupByStatus()
    } else if (this.groupBy === 'date') {
      this.groupedData = this.groupByDate()
    } else {
      this.groupedData = [{ group: 'all', items: this.appointments }]
    }
  }

  groupByStatus() {
    const groups = {}
    this.appointments.forEach(appointment => {
      const status = appointment.status
      if (!groups[status]) {
        groups[status] = []
      }
      groups[status].push(appointment)
    })

    return Object.entries(groups).map(([status, items]) => ({
      group: status,
      items
    }))
  }

  groupByDate() {
    const groups = {}
    this.appointments.forEach(appointment => {
      const date = new Date(appointment.appointment_date).toDateString()
      if (!groups[date]) {
        groups[date] = []
      }
      groups[date].push(appointment)
    })

    return Object.entries(groups).map(([date, items]) => ({
      group: date,
      items: items.sort((a, b) => new Date(a.appointment_date) - new Date(b.appointment_date))
    }))
  }

  next() {
    if (this.index >= this.groupedData.length) {
      return { done: true }
    }

    const group = this.groupedData[this.index]
    const result = {
      value: {
        groupName: group.group,
        appointments: group.items.map(appointment => ({
          ...appointment,
          formattedDate: new Date(appointment.appointment_date).toLocaleString(),
          statusColor: this.getStatusColor(appointment.status)
        })),
        count: group.items.length,
        index: this.index,
        total: this.groupedData.length
      },
      done: false
    }

    this.index++
    return result
  }

  getStatusColor(status) {
    const colors = {
      'pending': '#e6a23c',
      'confirmed': '#409eff',
      'completed': '#67c23a',
      'cancelled': '#f56c6c',
      'no_show': '#909399'
    }
    return colors[status] || '#909399'
  }

  reset() {
    this.index = 0
  }
}

// 知识库文章迭代器
export class KnowledgeIterator extends DataIterator {
  constructor(articles, category = null, sortBy = 'latest') {
    super()
    this.articles = articles || []
    this.category = category
    this.sortBy = sortBy
    this.index = 0
    this.processArticles()
  }

  processArticles() {
    let filtered = [...this.articles]

    // 按分类过滤
    if (this.category) {
      filtered = filtered.filter(article => article.category === this.category)
    }

    // 排序
    switch (this.sortBy) {
      case 'latest':
        filtered.sort((a, b) => new Date(b.published_at) - new Date(a.published_at))
        break
      case 'popular':
        filtered.sort((a, b) => b.view_count - a.view_count)
        break
      case 'liked':
        filtered.sort((a, b) => b.like_count - a.like_count)
        break
      default:
        break
    }

    this.processedArticles = filtered
  }

  next() {
    if (this.index >= this.processedArticles.length) {
      return { done: true }
    }

    const article = this.processedArticles[this.index]
    const result = {
      value: {
        id: article.id,
        title: article.title,
        summary: article.summary,
        author: article.author,
        category: article.category,
        tags: article.tags,
        viewCount: article.view_count,
        likeCount: article.like_count,
        publishedAt: new Date(article.published_at).toLocaleDateString(),
        isPopular: article.view_count > 1000,
        isRecommended: article.is_featured,
        index: this.index,
        total: this.processedArticles.length
      },
      done: false
    }

    this.index++
    return result
  }

  updateCategory(category) {
    this.category = category
    this.processArticles()
    this.index = 0
  }

  updateSort(sortBy) {
    this.sortBy = sortBy
    this.processArticles()
    this.index = 0
  }

  reset() {
    this.index = 0
  }
}

// 迭代器工厂
export class IteratorFactory {
  static createPaginatedIterator(data, pageSize = 10) {
    return new PaginatedIterator(data, pageSize)
  }

  static createFilteredIterator(data, filterFn) {
    return new FilteredIterator(data, filterFn)
  }

  static createDoctorIterator(doctors, filters = {}) {
    return new DoctorListIterator(doctors, filters)
  }

  static createAppointmentIterator(appointments, groupBy = null) {
    return new AppointmentIterator(appointments, groupBy)
  }

  static createKnowledgeIterator(articles, category = null, sortBy = 'latest') {
    return new KnowledgeIterator(articles, category, sortBy)
  }
}

// Vue 组合式函数
export function useDataIterator(data, type = 'paginated', options = {}) {
  let iterator

  switch (type) {
    case 'paginated':
      iterator = IteratorFactory.createPaginatedIterator(data, options.pageSize)
      break
    case 'filtered':
      iterator = IteratorFactory.createFilteredIterator(data, options.filterFn)
      break
    case 'doctor':
      iterator = IteratorFactory.createDoctorIterator(data, options.filters)
      break
    case 'appointment':
      iterator = IteratorFactory.createAppointmentIterator(data, options.groupBy)
      break
    case 'knowledge':
      iterator = IteratorFactory.createKnowledgeIterator(data, options.category, options.sortBy)
      break
    default:
      throw new Error(`Unknown iterator type: ${type}`)
  }

  // 辅助函数
  const nextItem = () => {
    const result = iterator.next()
    return result.done ? null : result.value
  }

  const getAllItems = () => {
    const items = []
    let result = iterator.next()
    while (!result.done) {
      items.push(result.value)
      result = iterator.next()
    }
    iterator.reset()
    return items
  }

  const reset = () => {
    iterator.reset()
  }

  return {
    iterator,
    nextItem,
    getAllItems,
    reset
  }
} 